package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.zzyl.common.core.redis.RedisCache;

import com.zzyl.common.exception.base.BaseException;

import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.vo.DeviceDetailVo;
import com.zzyl.nursing.vo.DevicePropertiesDataVo;
import com.zzyl.nursing.vo.ProductsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 设备表Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-08-26
 */
@Service
@Slf4j
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper,Device> implements IDeviceService
{
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private IoTDAClient iotDAClient;
    @Autowired
    private RedisCache redisCache;



    /**
     * 查询设备表列表
     * 
     * @param device 设备表
     * @return 设备表
     */
    @Override
    public List<Device> selectDeviceList(Device device)
    {
        return deviceMapper.selectDeviceList(device);
    }
    @Override
    public void syncProductList() {
        //1.先去获取华为云设备
        ListProductsResponse listProductsResponse = iotDAClient.listProducts(new ListProductsRequest());
        log.info("华为IOT平台返回的产品:{}",listProductsResponse);

        //2'得到数据
        List<ProductSummary> productsProducts = listProductsResponse.getProducts();

        List<ProductsVo> productsVos = productsProducts.stream()
                .map(p -> new ProductsVo( p.getName(),p.getProductId()))
                .collect(Collectors.toList());




        //将数据写入redis中
        redisCache.setCacheObject("IOT_ALL_PRODUCTS",productsVos);
    }

    @Override
    public List<ProductsVo> allProduct() {
        List<ProductsVo> productsVos = redisCache.getCacheObject("IOT_ALL_PRODUCTS");
        return productsVos;
    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //基本判断：1.设备名称或者标识不能重复
        //select count(*) from device where node_id=? or iot_id=?
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getDeviceName,deviceDto.getDeviceName());
        queryWrapper.or().eq(Device::getNodeId,deviceDto.getNodeId());
        long count = super.count(queryWrapper);
        if (count>0){
            throw new BaseException("设备名称或者标识码已存在");
        }
        //2.同一个位置不能重复绑定设备
        //select count(1) from device where product_key=1 and binding_location=1 and physical_location_type=1
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Device::getProductKey,deviceDto.getProductKey());
        wrapper.eq(Device::getBindingLocation,deviceDto.getBindingLocation());
        wrapper.eq(Device::getPhysicalLocationType,deviceDto.getPhysicalLocationType());
         count = super.count(wrapper);
         if (count>0){
             throw new BaseException("同一个位置不能重复绑定设备");
         }
         //3.去华为注册
        AddDeviceRequest addDeviceRequest = new AddDeviceRequest();
        AddDevice addDevice = new AddDevice();
        addDevice.setNodeId(deviceDto.getNodeId());
        addDevice.setProductId(deviceDto.getProductKey());
        addDevice.setDeviceName(deviceDto.getDeviceName());
        //生成密钥
        AuthInfo authInfo = new AuthInfo();
        String secret = UUID.randomUUID().toString().replace("-", "");
        authInfo.setSecret(secret);

        addDevice.setAuthInfo(authInfo);

        addDeviceRequest.setBody(addDevice);

        AddDeviceResponse addDeviceResponse = iotDAClient.addDevice(addDeviceRequest);
        log.info("华为IOT平台返回的设备信息:{}",addDeviceResponse);
        //4.保存到数据库device

        Device device = new Device();
        BeanUtils.copyProperties(deviceDto,device);
        device.setIotId(addDeviceResponse.getDeviceId());
        device.setSecret(secret);

        super.save(device);
    }

    @Override
    public DeviceDetailVo queryDeviceDetail(String iotId) {
    //1.从DB里面查询大部分数据
        Device device = super.getOne(Wrappers.<Device>lambdaQuery().eq(Device::getIotId, iotId));
        if (device==null){
            throw new BaseException("设备不存在");
        }
        DeviceDetailVo deviceDetailVo = new DeviceDetailVo();
        BeanUtils.copyProperties(device,deviceDetailVo);
        //2.去IOT平台查询小部分数据
        ShowDeviceRequest showDeviceRequest = new ShowDeviceRequest();
        showDeviceRequest.setDeviceId(iotId);
        ShowDeviceResponse response = iotDAClient.showDevice(showDeviceRequest);
        log.info("查询设备详情返回:{}", response);


        deviceDetailVo.setDeviceStatus(response.getStatus());
         String activeTimeStr=response.getActiveTime();
         //注意：有可能没有激活
        if(StringUtils.isNotEmpty(activeTimeStr)) {
            LocalDateTime activeTime = LocalDateTimeUtil.parse(activeTimeStr, DatePattern.UTC_MS_PATTERN);
            //时区转换
            activeTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC)).
                    withZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime();

            deviceDetailVo.setActiveTime(activeTime);
        }
        return deviceDetailVo;
    }

    @Override
    public List<DevicePropertiesDataVo> queryServiceProperties(String iotId) {
        ShowDeviceShadowRequest showDeviceShadowRequest = new ShowDeviceShadowRequest();
        showDeviceShadowRequest.setDeviceId(iotId);
        ShowDeviceShadowResponse response = iotDAClient.showDeviceShadow(showDeviceShadowRequest);
        log.info("查询设备属性返回:{}", response);
        if (CollectionUtils.isEmpty(response.getShadow())){
            return new ArrayList<>();
        }
        Object properties = response.getShadow().get(0).getReported().getProperties();
        String  eventTimeStr = response.getShadow().get(0).getReported().getEventTime();
        //转日期
        LocalDateTime eventTime = LocalDateTimeUtil.parse(eventTimeStr, "yyyyMMdd'T'HHmmss'Z'");
        List<DevicePropertiesDataVo> resultList=new ArrayList<>();

        JSONObject parsedObj = JSONUtil.parseObj(properties);
        parsedObj.forEach((key,value)->{
            DevicePropertiesDataVo dataVo = new DevicePropertiesDataVo();
            dataVo.setFunctionId(key);
            dataVo.setValue(value);
            dataVo.setEventTime(eventTime);
            resultList.add(dataVo);
        });
        return resultList;


    }

    @Transactional
    @Override
    public String deleteDeviceByIds(DeviceDto dto) {
        //1.先删除数据库中的数据
        deviceMapper.deleteDeviceById(dto.getIotId());
        //2.在删除IOT平台中的数据
        DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
        deleteDeviceRequest.setDeviceId(dto.getIotId());
        iotDAClient.deleteDevice(deleteDeviceRequest);
        log.info("删除设备成功");
        redisCache.deleteObject("IOT_ALL_PRODUCTS");

        return "删除设备成功";
    }


}
